-- movement_system.lua
-- 自适应帧率的运动系统 - 集成地形管理器支持，斜坡作为倾斜平台

local Vector2 = require("vector")
local DisplayConfig = require("Script.DisplayConfig")
local LevelTileConfig = require("LevelTileConfig")

local MovementSystem = {}
MovementSystem.__index = MovementSystem

function MovementSystem.new(screenWidth, screenHeight, sceneBounds, keyboardInput)
    -- 使用关卡边界作为运动系统边界
    local levelBounds = LevelTileConfig.getLevelBounds()
    
    local system = {
        entities = {},
        keyboardInput = keyboardInput,
        baseTimestep = 1/60,
        currentTimestep = 1/60,
        minTimestep = 1/120,
        maxTimestep = 1/30,
        frameTimes = {},
        averageFPS = 60,
        frameCount = 0,
        currentTime = 0,
        gravity = Vector2.new(0, -3100),
        baseMoveSpeed = 400,
        sprintMoveSpeed = 800,
        acceleration = 5000,
        deceleration = 850,
        airControl = 0.8,
        friction = 0.7,
        airResistance = 0.998,
        maxFallSpeed = 1200,
        rollSpeed = 400,
        rollDuration = 0.4,
        rollCooldown = 0.1,
        isSprinting = false,
        sprintDirection = 0,
        doubleTapTime = 0.3,
        lastKeyPressTime = {A = 0, D = 0},
        lastAPressed = false,
        lastDPressed = false,
        rollTimer = 0,
        rollDirection = 0,
        lastShiftPressed = false,
        bounds = levelBounds,  -- 使用关卡边界
        groundPlatforms = {},
        characterMonitor = nil,
        sceneManager = nil,
        cachedProperties = nil,
        lastPropertyUpdate = 0,
        _transitionInProgress = false,
        currentSceneTransitionTime = 0,
        _lastAdaptationTime = 0,
        _adaptationCount = 0,
        _levelManager = nil,  -- 关卡管理器引用
        _terrainManager = nil, -- 地形管理器引用
        _positionTracking = true,  -- 位置追踪开关
        _lastPositionLogTime = 0,  -- 上次记录位置时间
        _positionLogInterval = 1.0,  -- 位置记录间隔（秒）
        _initialPositionLogged = false,  -- 初始位置是否已记录
        _debugGroundDetection = true,  -- 地面检测调试开关
        _debugSlopeDetection = true,   -- 斜坡检测调试开关
        _isFirstUpdate = true,  -- 首次更新标志
        
        -- 新增：Boss触发器相关
        _bossTriggerDetected = false,  -- Boss触发器检测标志
        _bossTriggerData = nil,         -- 触发器数据
        _onBossTriggerCallback = nil    -- Boss触发器回调
    }
    
    setmetatable(system, MovementSystem)
    
    -- 初始地面平台（将在地形管理器初始化时被替换）
    local groundPlatform = {
        x = levelBounds.left,
        y = -700,
        width = levelBounds.width,
        height = 50
    }
    table.insert(system.groundPlatforms, groundPlatform)
    
    print("自适应帧率运动系统初始化完成")
    print("关卡边界: 宽度=" .. levelBounds.width .. ", 高度=" .. levelBounds.height)
    
    return system
end

-- 注册实体到运动系统 - 添加初始位置追踪
function MovementSystem:registerEntity(entityData)
    if not entityData.id then
        error("实体必须包含id字段")
    end
    
    local requiredFields = {"position", "velocity", "maxSpeed", "mass", "radius"}
    for _, field in ipairs(requiredFields) do
        if entityData[field] == nil then
            error("实体缺少必要字段: " .. field)
        end
    end
    
    local entity = {
        id = entityData.id,
        position = Vector2.new(entityData.position.x, entityData.position.y),
        velocity = Vector2.new(entityData.velocity.x, entityData.velocity.y),
        maxSpeed = entityData.maxSpeed,
        mass = entityData.mass,
        isGrounded = false,
        node = entityData.node,
        radius = entityData.radius,
        lastDirection = 1,
        moveInput = 0,
        currentSpeed = 0,
        wasGrounded = false,
        currentSlope = nil,  -- 当前所在的斜坡
        physicsState = {
            horizontalSpeed = 0,
            verticalSpeed = 0,
            isInAir = true,
            inputDirection = 0,
            jumpHorizontalSpeed = 0,
            isRolling = false,
            rollTimer = 0,
        },
        _normalizedVelocity = Vector2.new(0, 0),
        _lastHorizontalSpeed = 0,
        _lastInputDirection = 0,
        _positionHistory = {},  -- 位置历史记录
        _lastGroundedTime = 0  -- 上次落地时间
    }
    
    self.entities[entityData.id] = entity
    
    -- 记录初始位置
    if self._positionTracking then
        print("====================================")
        print("实体注册 - 初始位置追踪")
        print("实体ID: " .. entityData.id)
        print(string.format("初始位置: (%.1f, %.1f)", entity.position.x, entity.position.y))
        print(string.format("初始速度: (%.1f, %.1f)", entity.velocity.x, entity.velocity.y))
        print(string.format("角色半径: %.1f", entity.radius))
        print(string.format("角色底部: %.1f", entity.position.y - entity.radius))
        
        -- 获取当前切片
        local row, col = LevelTileConfig.getTileByPosition(entity.position.x, entity.position.y)
        print(string.format("初始切片: %d_%d", row, col))
        
        -- 检查是否在地面平台上
        if self._terrainManager then
            local walkable = self._terrainManager:isWalkable(entity.position.x, entity.position.y, entity.radius)
            local onSlope, slope = self._terrainManager:isOnSlope(entity.position.x, entity.position.y, entity.radius)
            
            print(string.format("地形管理器检查: 可行走=%s, 在斜坡上=%s", 
                tostring(walkable), tostring(onSlope)))
            
            if onSlope then
                print(string.format("斜坡斜率: %.4f", slope.k))
            end
        end
        
        print("====================================")
    end
    
    print("实体注册成功: " .. entityData.id)
    
    return entity
end

-- 注销实体
function MovementSystem:unregisterEntity(entityId)
    if self.entities[entityId] then
        self.entities[entityId] = nil
        print("实体注销: " .. entityId)
        return true
    end
    return false
end

-- 检查实体是否已注册
function MovementSystem:isEntityRegistered(entityId)
    return self.entities[entityId] ~= nil
end

-- 获取所有已注册的实体ID
function MovementSystem:getRegisteredEntities()
    local ids = {}
    for id, _ in pairs(self.entities) do
        table.insert(ids, id)
    end
    return ids
end

-- 设置角色监视器引用
function MovementSystem:setCharacterMonitor(characterMonitor)
    self.characterMonitor = characterMonitor
end

-- 设置场景管理器引用
function MovementSystem:setSceneManager(sceneManager)
    self.sceneManager = sceneManager
end

-- 设置关卡管理器引用
function MovementSystem:setLevelManager(levelManager)
    self._levelManager = levelManager
    print("运动系统：设置关卡管理器引用")
    
    -- 从关卡管理器获取地面平台
    if levelManager then
        self.groundPlatforms = levelManager:getGroundPlatforms() or {}
        print("运动系统：从关卡管理器加载了 " .. #self.groundPlatforms .. " 个地面平台")
    end
end

-- 设置地形管理器引用
function MovementSystem:setTerrainManager(terrainManager)
    self._terrainManager = terrainManager
    print("运动系统：设置地形管理器引用")
    
    -- 从地形管理器获取碰撞平台
    if terrainManager then
        self.groundPlatforms = terrainManager:getCollisionPlatforms() or {}
        print("运动系统：从地形管理器加载了 " .. #self.groundPlatforms .. " 个碰撞平台")
        
        -- 输出地形信息用于调试
        if self._debugGroundDetection then
            print("=== 地形管理器信息 ===")
            local terrainData = terrainManager:getTerrainData()
            local terrainCounts = {
                normal = 0,
                gap = 0,
                slope = 0,
                wall = 0,
                boss_trigger = 0
            }
            
            for key, terrain in pairs(terrainData) do
                if terrain.type then
                    terrainCounts[terrain.type] = (terrainCounts[terrain.type] or 0) + 1
                end
            end
            
            for typeName, count in pairs(terrainCounts) do
                print(string.format("%s: %d", typeName, count))
            end
            
            -- 打印所有斜坡详情
            for key, terrain in pairs(terrainData) do
                if terrain.type == "slope" then
                    print(string.format("斜坡: %02d_%02d -> %02d_%02d, 斜率: %.4f", 
                        terrain.startRow, terrain.startCol,
                        terrain.endRow, terrain.endCol,
                        terrain.k))
                elseif terrain.type == "boss_trigger" then
                    print(string.format("Boss触发器: %02d_%02d, 位置: (%.1f, %.1f)", 
                        terrain.row, terrain.col, terrain.x, terrain.y))
                end
            end
            print("=======================")
        end
    end
end

-- 设置Boss触发器回调
function MovementSystem:setBossTriggerCallback(callback)
    self._onBossTriggerCallback = callback
    print("运动系统：设置Boss触发器回调")
end

-- 从Unit获取移动属性（带缓存）
function MovementSystem:_getUnitProperties()
    if self.cachedProperties and (self.currentTime - self.lastPropertyUpdate) < 0.1 then
        return self.cachedProperties
    end
    
    local properties
    if not self.characterMonitor then
        properties = {
            baseMoveSpeed = 400,
            sprintMoveSpeed = 800,
            acceleration = 5000,
            deceleration = 850,
            airControl = 0.8,
            friction = 0.7,
            airResistance = 0.998,
            maxFallSpeed = 1200,
            rollSpeed = 400,
            rollDistance = 160,
            rollDuration = 0.4,
            rollCooldown = 0.1,
            rollInvincibleTime = 0.15
        }
    else
        local Unit = require("Script.Unit")
        local unitInstance = self.characterMonitor:getState()
        
        properties = {
            baseMoveSpeed = Unit.getMoveSpeed(unitInstance),
            sprintMoveSpeed = (unitInstance.definition.sprintMove or 600),
            acceleration = Unit.getAcceleration(unitInstance),
            deceleration = Unit.getDeceleration(unitInstance),
            airControl = Unit.getAirControl(unitInstance),
            friction = Unit.getFriction(unitInstance),
            airResistance = Unit.getAirResistance(unitInstance),
            maxFallSpeed = Unit.getMaxFallSpeed(unitInstance),
            rollSpeed = Unit.getRollSpeed(unitInstance),
            rollDistance = Unit.getRollDistance(unitInstance),
            rollDuration = Unit.getRollDuration(unitInstance),
            rollCooldown = Unit.getRollCooldown(unitInstance),
            rollInvincibleTime = Unit.getRollInvincibleTime(unitInstance)
        }
    end
    
    self.cachedProperties = properties
    self.lastPropertyUpdate = self.currentTime
    
    return properties
end

-- 内部方法：自适应输入处理
function MovementSystem:_handleInputAdaptive(entity, dt)
    local aPressed = self.keyboardInput:isKeyPressed("A")
    local dPressed = self.keyboardInput:isKeyPressed("D")
    
    self:_checkDoubleTap(aPressed, dPressed)
    
    local inputX = 0
    if aPressed then inputX = inputX - 1 end
    if dPressed then inputX = inputX + 1 end
    
    entity.moveInput = inputX
    
    if inputX ~= 0 then
        entity.lastDirection = inputX > 0 and 1 or -1
    end
    
    -- 检查是否在翻滚中（通过角色监视器）
    local isRolling = false
    local rollDirection = 1
    if self.characterMonitor then
        isRolling = self.characterMonitor:isRolling()
        rollDirection = self.characterMonitor:getRollDirection()
    end
    
    -- 翻滚中不接受普通移动输入，保持翻滚速度并锁定方向
    if isRolling then
        local properties = self:_getUnitProperties()
        local rollDistance = properties.rollDistance or 160
        local rollDuration = properties.rollDuration or 0.4
        
        -- 计算实际翻滚速度
        local actualRollSpeed = (rollDistance / rollDuration)
        
        -- 翻滚时锁定方向为开始翻滚时的方向
        entity.velocity.x = rollDirection * actualRollSpeed
        entity.moveInput = 0  -- 清除输入，防止干扰
        return
    end
    
    -- 从Unit获取移动属性（使用缓存）
    local properties = self:_getUnitProperties()
    local targetSpeed = self.isSprinting and properties.sprintMoveSpeed or properties.baseMoveSpeed
    local targetVelocityX = inputX * targetSpeed
    
    if self.isSprinting and inputX == 0 then
        self.isSprinting = false
        self.sprintDirection = 0
    end
    
    local currentVelocityX = entity.velocity.x
    local velocityDifference = targetVelocityX - currentVelocityX
    
    -- 帧率自适应的速度控制
    if math.abs(velocityDifference) > 0.1 then
        if math.abs(inputX) > 0.1 then
            local accelerationRate = entity.isGrounded and properties.acceleration or properties.acceleration * properties.airControl
            local normalizedAcceleration = accelerationRate * dt * (60 * dt)
            local acceleration = math.sign(velocityDifference) * math.min(math.abs(velocityDifference), normalizedAcceleration)
            entity.velocity.x = entity.velocity.x + acceleration
        else
            if entity.isGrounded then
                if math.abs(currentVelocityX) < 200 then
                    local normalizedDeceleration = properties.deceleration * dt * (60 * dt)
                    local deceleration = math.sign(currentVelocityX) * math.min(math.abs(currentVelocityX), normalizedDeceleration)
                    entity.velocity.x = entity.velocity.x - deceleration
                else
                    entity.velocity.x = entity.velocity.x * (properties.friction ^ (60 * dt))
                end
                
                if math.abs(entity.velocity.x) < 5 then
                    entity.velocity.x = 0
                end
            else
                entity.velocity.x = entity.velocity.x * (properties.airResistance ^ (60 * dt))
            end
        end
    end
    
    self.lastAPressed = aPressed
    self.lastDPressed = dPressed
end

-- 更新所有实体状态 - 支持斜坡（作为倾斜平台）
function MovementSystem:update(dt)
    self.currentTime = self.currentTime + dt
    self.frameCount = self.frameCount + 1
    
    self:updateFrameStats(dt)
    self:adaptTimestep()
    
    local effectiveDt = math.min(dt, self.currentTimestep)
    
    for id, entity in pairs(self.entities) do
        -- 位置追踪：每秒记录一次
        if self._positionTracking and (self.currentTime - self._lastPositionLogTime) >= self._positionLogInterval then
            self:logEntityPosition(id, entity)
            self._lastPositionLogTime = self.currentTime
        end
        
        -- 保存上一帧的地面状态
        entity.wasGrounded = entity.isGrounded
        
        -- 1. 处理输入
        self:_updateKeyStates()
        self:_handleInputAdaptive(entity, effectiveDt)
        
        -- 2. 应用物理力（重力、加速度等）
        self:_applyPhysicsAdaptive(entity, effectiveDt)
        
        -- 3. 临时更新位置
        local newX = entity.position.x + entity.velocity.x * effectiveDt
        local newY = entity.position.y + entity.velocity.y * effectiveDt
        
        -- 4. 检查和处理碰撞（按顺序）
        
        -- 4.1 水平移动和边界检查
        entity.position.x = newX
        self:_handleBoundaries(entity)
        
        -- 4.2 垂直移动
        entity.position.y = newY
        
        -- 4.3 地面碰撞检测（支持斜坡作为倾斜平台）
        self:checkGroundCollision(entity)
        
        -- 4.4 边界检查（垂直方向）
        self:_handleBoundaries(entity)
        
        -- 4.5 检查墙壁阻挡
        self:_checkWallCollision(entity)
        
        -- 5. 处理状态变化
        self:_updatePhysicsState(entity, effectiveDt)
        
        -- 6. 处理落地事件
        if not entity.wasGrounded and entity.isGrounded then
            self:_handleLanding(entity)
            entity._lastGroundedTime = self.currentTime
        end
        
        -- 7. 检查Boss触发器（只在玩家实体上检查）
        if id == "player" and entity.isGrounded and not self._bossTriggerDetected then
            self:checkBossTrigger(entity)
        end
        
        -- 8. 更新节点位置
        if entity.node then
            entity.node.x = entity.position.x
            entity.node.y = entity.position.y
        end
        
        -- 记录位置历史（用于调试）
        if #entity._positionHistory > 100 then
            table.remove(entity._positionHistory, 1)
        end
        table.insert(entity._positionHistory, {
            time = self.currentTime,
            x = entity.position.x,
            y = entity.position.y,
            isGrounded = entity.isGrounded,
            velocityY = entity.velocity.y,
            onSlope = entity.currentSlope ~= nil
        })
    end
    
    -- 重置首次更新标志
    if self._isFirstUpdate then
        self._isFirstUpdate = false
    end
end

-- 检查Boss触发器
function MovementSystem:checkBossTrigger(entity)
    if not self._terrainManager or not entity.isGrounded then return end
    
    local platform = self._terrainManager:getStandingPlatform(
        entity.position.x, 
        entity.position.y, 
        entity.radius
    )
    
    if platform and platform.type == "boss_trigger" then
        if not self._bossTriggerDetected then
            self._bossTriggerDetected = true
            self._bossTriggerData = platform.triggerData
            
            if self._debugGroundDetection then
                print(string.format("检测到Boss触发器: 位置(%.1f, %.1f)", 
                    entity.position.x, entity.position.y))
            end
            
            -- 触发回调
            if self._onBossTriggerCallback then
                self._onBossTriggerCallback(platform.triggerData)
            end
        end
    end
end

-- 重置Boss触发器状态
function MovementSystem:resetBossTrigger()
    self._bossTriggerDetected = false
    self._bossTriggerData = nil
    print("运动系统：Boss触发器状态已重置")
end

-- 更新帧率统计
function MovementSystem:updateFrameStats(dt)
    table.insert(self.frameTimes, dt)
    
    if #self.frameTimes > 60 then
        table.remove(self.frameTimes, 1)
    end
    
    local totalTime = 0
    for _, frameTime in ipairs(self.frameTimes) do
        totalTime = totalTime + frameTime
    end
    
    if #self.frameTimes > 0 then
        self.averageFPS = #self.frameTimes / totalTime
    end
end

-- 自适应调整时间步长
function MovementSystem:adaptTimestep()
    if self.frameCount % 30 ~= 0 then
        return
    end
    
    local oldTimestep = self.currentTimestep
    
    if self.averageFPS > 100 then
        self.currentTimestep = self.minTimestep
    elseif self.averageFPS < 40 then
        self.currentTimestep = self.maxTimestep
    else
        self.currentTimestep = self.baseTimestep
    end
    
    if oldTimestep ~= self.currentTimestep then
        self._adaptationCount = self._adaptationCount + 1
        self._lastAdaptationTime = self.currentTime
        
        print(string.format("帧率自适应调整: %.1f FPS -> 时间步长 %.4f (%.0fHz)", 
            self.averageFPS, self.currentTimestep, 1/self.currentTimestep))
    end
end

-- 内部方法：更新物理状态
function MovementSystem:_updatePhysicsState(entity, dt)
    local physics = entity.physicsState
    
    local isRolling = false
    if self.characterMonitor then
        isRolling = self.characterMonitor:isRolling()
    end
    
    physics.isRolling = isRolling
    
    local currentSpeed = math.abs(entity.velocity.x)
    entity.currentSpeed = currentSpeed
    
    if currentSpeed ~= entity._lastHorizontalSpeed then
        physics.horizontalSpeed = currentSpeed
        entity._lastHorizontalSpeed = currentSpeed
    end
    
    physics.verticalSpeed = entity.velocity.y
    physics.isInAir = not entity.isGrounded
    
    if entity.moveInput ~= entity._lastInputDirection then
        physics.inputDirection = entity.moveInput
        entity._lastInputDirection = entity.moveInput
    end
    
    if not self._wasInAir and physics.isInAir then
        physics.jumpHorizontalSpeed = currentSpeed
    end
    
    self._wasInAir = physics.isInAir
end

-- 内部方法：自适应物理应用（斜坡作为倾斜平台，无滑落）
function MovementSystem:_applyPhysicsAdaptive(entity, dt)
    local properties = self:_getUnitProperties()
    
    -- 应用重力（只在空中应用）
    if not entity.isGrounded then
        local normalizedGravity = self.gravity.y * dt * (60 * dt)
        entity.velocity.y = entity.velocity.y + normalizedGravity
    else
        -- 在地面上时，如果有斜坡（作为倾斜平台），确保站在斜坡上
        if entity.currentSlope then
            local slope = entity.currentSlope
            local expectedGroundY = slope.k * entity.position.x + slope.b
            local entityBottom = entity.position.y - entity.radius
            
            -- 确保站在斜坡的正确高度上（无滑落功能）
            if math.abs(entityBottom - expectedGroundY) > 1 then
                entity.position.y = expectedGroundY + entity.radius
            end
            
            -- 在斜坡上时，重置垂直速度（无滑落）
            entity.velocity.y = 0
        else
            -- 平地上，重置垂直速度
            if entity.velocity.y < 0 then
                entity.velocity.y = 0
            end
        end
    end
    
    local isRolling = false
    if self.characterMonitor then
        isRolling = self.characterMonitor:isRolling()
    end
    
    if not isRolling then
        local horizontalSpeed = math.abs(entity.velocity.x)
        local maxSpeed = self.isSprinting and properties.sprintMoveSpeed or properties.baseMoveSpeed
        if horizontalSpeed > maxSpeed then
            entity.velocity.x = entity.velocity.x / horizontalSpeed * maxSpeed
        end
    end
    
    if entity.velocity.y < -properties.maxFallSpeed then
        entity.velocity.y = -properties.maxFallSpeed
    end
end

-- 内部方法：检测双击冲刺
function MovementSystem:_checkDoubleTap(aPressed, dPressed)
    if not (aPressed or dPressed) then return end
    
    if aPressed and not self.lastAPressed then
        if self.currentTime - self.lastKeyPressTime.A < self.doubleTapTime then
            self.isSprinting = true
            self.sprintDirection = -1
        end
        self.lastKeyPressTime.A = self.currentTime
    end
    
    if dPressed and not self.lastDPressed then
        if self.currentTime - self.lastKeyPressTime.D < self.doubleTapTime then
            self.isSprinting = true
            self.sprintDirection = 1
        end
        self.lastKeyPressTime.D = self.currentTime
    end
end

-- 内部方法：处理边界碰撞
function MovementSystem:_handleBoundaries(entity)
    local bounds = self.bounds
    
    -- X轴边界检查
    if entity.position.x - entity.radius < bounds.left then
        entity.position.x = bounds.left + entity.radius
        entity.velocity.x = math.max(0, entity.velocity.x)
    elseif entity.position.x + entity.radius > bounds.right then
        entity.position.x = bounds.right - entity.radius
        entity.velocity.x = math.min(0, entity.velocity.x)
    end
    
    -- Y轴边界检查（顶部）
    if entity.position.y + entity.radius > bounds.top then
        entity.position.y = bounds.top - entity.radius
        entity.velocity.y = math.min(entity.velocity.y, 0)
    end
    
    -- Y轴底部边界检查（防止掉出世界）
    if entity.position.y - entity.radius < bounds.bottom - 1000 then  -- 允许掉出一定范围
        entity.position.y = bounds.bottom - 1000 + entity.radius
        entity.velocity.y = 0
        
        if self._debugGroundDetection then
            print(string.format("边界检测: 角色接近世界底部 y=%.1f", entity.position.y))
        end
    end
end

-- 内部方法：检查墙壁阻挡
function MovementSystem:_checkWallCollision(entity)
    if not self._terrainManager then return end
    
    local isBlocked = self._terrainManager:isWallBlocked(
        entity.position.x, 
        entity.position.y, 
        entity.lastDirection, 
        entity.radius
    )
    
    if isBlocked then
        -- 如果撞到墙壁，停止水平移动
        if self._debugSlopeDetection and entity.velocity.x ~= 0 then
            print(string.format("墙壁阻挡: 位置(%.1f, %.1f), 速度x=%.1f", 
                entity.position.x, entity.position.y, entity.velocity.x))
        end
        
        entity.velocity.x = 0
    end
end

-- 修正版：地面碰撞检测（支持斜坡作为倾斜平台）
function MovementSystem:checkGroundCollision(entity)
    entity.isGrounded = false
    entity.currentSlope = nil
    
    -- 使用地形管理器（如果可用）
    if self._terrainManager then
        local platform = self._terrainManager:getStandingPlatform(
            entity.position.x, 
            entity.position.y, 
            entity.radius
        )
        
        if platform then
            -- 检查是否是Boss触发器
            if platform.type == "boss_trigger" then
                -- Boss触发器可以站立，但不触发常规地面逻辑
                entity.isGrounded = true
                entity.velocity.y = 0
                
                -- 确保站在触发器上
                local targetY = platform.y + entity.radius
                if math.abs(entity.position.y - targetY) > 1 then
                    entity.position.y = targetY
                end
                return
            end
            
            -- 计算目标Y位置
            local targetY = platform.y + entity.radius
            
            -- 平滑移动到平台顶部
            if math.abs(entity.position.y - targetY) > 1 then
                entity.position.y = targetY
            end
            
            entity.velocity.y = 0
            entity.isGrounded = true
            
            if platform.isSlope then
                entity.currentSlope = platform.slopeData
                
                if self._debugSlopeDetection and self.frameCount % 30 == 0 then
                    print(string.format("站在斜坡上（倾斜平台）: 位置(%.1f, %.1f), 斜率=%.4f", 
                        entity.position.x, entity.position.y, platform.slopeData.k))
                end
            end
            
            return
        end
    end
    
    -- 如果没有地形管理器，使用原来的检测逻辑
    if #self.groundPlatforms == 0 then
        -- 如果没有地面平台，使用边界地面作为备用
        local bounds = self.bounds
        local entityBottom = entity.position.y - entity.radius
        
        if entityBottom <= bounds.bottom + 5 and entity.velocity.y <= 0 then
            entity.position.y = bounds.bottom + entity.radius
            entity.velocity.y = 0
            entity.isGrounded = true
        end
        return
    end
    
    -- 寻找合适的平台
    local bestPlatform = nil
    local minVerticalDistance = math.huge
    
    -- 首次更新使用更大的检测范围，后续使用正常范围
    local maxDetectionRange = self._isFirstUpdate and 200 or 50
    
    for _, platform in ipairs(self.groundPlatforms) do
        local platformTop = platform.y + platform.height
        local entityBottom = entity.position.y - entity.radius
        
        -- 检查水平对齐
        local leftBoundary = platform.x - entity.radius
        local rightBoundary = platform.x + platform.width + entity.radius
        local isHorizontallyAligned = entity.position.x >= leftBoundary and 
                                     entity.position.x <= rightBoundary
        
        if isHorizontallyAligned then
            -- 计算垂直距离：正值表示角色在平台上方
            local verticalDistance = entityBottom - platformTop
            
            -- 角色必须在平台上方（垂直距离>=0）且在一定范围内
            -- 同时在下落或静止
            local isWithinRange = verticalDistance >= 0 and verticalDistance <= maxDetectionRange
            local isFallingOrStable = entity.velocity.y <= 0
            
            if isWithinRange and isFallingOrStable then
                -- 找到最近的平台
                if verticalDistance < minVerticalDistance then
                    minVerticalDistance = verticalDistance
                    bestPlatform = platform
                end
            end
            
            -- 调试信息
            if self._debugGroundDetection and entity.id == "player" then
                if self.frameCount % 10 == 0 then  -- 每10帧输出一次，避免日志过多
                    print(string.format("地面检测[检查]: 平台(%.1f, %.1f) 垂直距离=%.1f 范围=%s 下落=%s",
                        platform.x, platform.y, verticalDistance, 
                        tostring(isWithinRange), tostring(isFallingOrStable)))
                end
            end
        end
    end
    
    if bestPlatform then
        -- 站在平台上
        local platformTop = bestPlatform.y + bestPlatform.height
        local targetY = platformTop + entity.radius
        
        -- 如果角色离平台很近，平滑移动到平台顶部
        if math.abs(entity.position.y - targetY) > 1 then
            entity.position.y = targetY
        end
        
        entity.velocity.y = 0
        entity.isGrounded = true
        
        -- 调试信息
        if self._debugGroundDetection then
            print(string.format("地面检测[成功]: 平台(%.1f, %.1f) 距离=%.1f 角色y=%.1f",
                bestPlatform.x, bestPlatform.y, minVerticalDistance, entity.position.y))
        end
    else
        -- 调试信息：为什么没有找到合适的平台
        if self._debugGroundDetection and entity.id == "player" and entity.velocity.y <= 0 then
            local entityBottom = entity.position.y - entity.radius
            if self.frameCount % 30 == 0 then  -- 每30帧输出一次
                print(string.format("地面检测[失败]: 底部y=%.1f 速度y=%.1f 平台数=%d",
                    entityBottom, entity.velocity.y, #self.groundPlatforms))
            end
        end
    end
end

-- 内部方法：处理落地事件
function MovementSystem:_handleLanding(entity)
    local properties = self:_getUnitProperties()
    local currentSpeed = math.abs(entity.velocity.x)
    
    if currentSpeed < 400 then
        entity.velocity.x = entity.velocity.x * 0.7  -- 轻微减速
    else
        entity.velocity.x = entity.velocity.x * properties.friction
    end
    
    -- 调试信息
    if self._debugGroundDetection then
        local onSlopeText = entity.currentSlope and " (在斜坡上)" or ""
        print(string.format("落地事件%s: 速度从(%.1f, %.1f)调整", 
            onSlopeText, entity.velocity.x, entity.velocity.y))
    end
end

-- 新增：更新按键状态
function MovementSystem:_updateKeyStates()
    if not self.keyboardInput then
        return
    end
    
    local shiftPressed = self.keyboardInput:isKeyPressed("Shift") or 
                        self.keyboardInput:isKeyPressed("LShift") or 
                        self.keyboardInput:isKeyPressed("RShift")
    
    self.lastShiftPressed = shiftPressed
end

-- 添加地面平台
function MovementSystem:addGroundPlatform(platform)
    table.insert(self.groundPlatforms, platform)
    return true
end

-- 批量添加地面平台
function MovementSystem:addGroundPlatforms(platforms)
    for _, platform in ipairs(platforms) do
        self:addGroundPlatform(platform)
    end
    return #platforms
end

-- 清除所有地面平台
function MovementSystem:clearGroundPlatforms()
    self.groundPlatforms = {}
    return true
end

-- 设置地面高度（用于初始化）
function MovementSystem:setGroundHeight(newHeight)
    self.groundPlatforms = {}
    
    local groundPlatform = {
        x = self.bounds.left,
        y = newHeight,
        width = self.bounds.width,
        height = 50
    }
    
    table.insert(self.groundPlatforms, groundPlatform)
    print("地面高度已设置为: " .. newHeight)
    return true
end

-- 根据ID获取实体
function MovementSystem:getEntity(id)
    return self.entities[id]
end

-- 获取实体移动状态
function MovementSystem:getEntityMoveStatus(id)
    local entity = self.entities[id]
    if not entity then return nil end
    
    return {
        physicsState = {
            horizontalSpeed = entity.physicsState.horizontalSpeed,
            verticalSpeed = entity.physicsState.verticalSpeed,
            isInAir = entity.physicsState.isInAir,
            inputDirection = entity.physicsState.inputDirection,
            jumpHorizontalSpeed = entity.physicsState.jumpHorizontalSpeed,
            isRolling = entity.physicsState.isRolling,
            rollTimer = entity.physicsState.rollTimer
        },
        lastDirection = entity.lastDirection,
        isGrounded = entity.isGrounded,
        currentSlope = entity.currentSlope,
        isSprinting = self.isSprinting,
        sprintDirection = self.sprintDirection,
        position = {x = entity.position.x, y = entity.position.y}
    }
end

-- 获取冲刺状态
function MovementSystem:getSprintStatus()
    local properties = self:_getUnitProperties()
    
    return {
        isSprinting = self.isSprinting,
        sprintDirection = self.sprintDirection,
        sprintSpeed = properties.sprintMoveSpeed,
        normalSpeed = properties.baseMoveSpeed
    }
end

-- 获取实体位置
function MovementSystem:getPosition(id)
    local entity = self.entities[id]
    return entity and {x = entity.position.x, y = entity.position.y} or nil
end

-- 强制设置实体位置
function MovementSystem:setPosition(id, x, y)
    local entity = self.entities[id]
    if entity then
        entity.position.x = x
        entity.position.y = y
        
        if entity.node then
            entity.node.x = x
            entity.node.y = y
        end
        return true
    end
    return false
end

-- 应用冲量到实体
function MovementSystem:applyImpulse(id, impulseX, impulseY)
    local entity = self.entities[id]
    if entity then
        entity.velocity.x = entity.velocity.x + impulseX / entity.mass
        entity.velocity.y = entity.velocity.y + impulseY / entity.mass
        return true
    end
    return false
end

-- 设置实体速度
function MovementSystem:setVelocity(id, velocityX, velocityY)
    local entity = self.entities[id]
    if entity then
        entity.velocity.x = velocityX
        entity.velocity.y = velocityY
        return true
    end
    return false
end

-- 获取实体速度
function MovementSystem:getVelocity(id)
    local entity = self.entities[id]
    return entity and {x = entity.velocity.x, y = entity.velocity.y} or nil
end

-- 新增：记录实体位置
function MovementSystem:logEntityPosition(entityId, entity)
    if not entity then return end
    
    -- 记录基本位置信息
    local logMsg = string.format("[位置追踪] 实体: %s, 时间: %.1fs", 
        entityId, self.currentTime)
    print(logMsg)
    
    print(string.format("  当前位置: (%.1f, %.1f)", entity.position.x, entity.position.y))
    print(string.format("  当前速度: (%.1f, %.1f)", entity.velocity.x, entity.velocity.y))
    print(string.format("  是否在地面: %s", tostring(entity.isGrounded)))
    
    -- 检查斜坡状态
    if entity.currentSlope then
        print(string.format("  在斜坡上: 斜率=%.4f", entity.currentSlope.k))
    end
    
    -- 获取当前切片
    local row, col = LevelTileConfig.getTileByPosition(entity.position.x, entity.position.y)
    print(string.format("  当前切片: %d_%d", row, col))
    
    -- 获取切片信息
    local tileInfo = LevelTileConfig.getTileInfoByPosition(entity.position.x, entity.position.y)
    if tileInfo then
        print(string.format("  切片文件: %s", tileInfo.filename))
        print(string.format("  切片地面高度: %.1f", tileInfo.groundY))
    end
    
    -- 检查地形管理器
    if self._terrainManager then
        local walkable = self._terrainManager:isWalkable(entity.position.x, entity.position.y, entity.radius)
        local onSlope = entity.currentSlope ~= nil
        print(string.format("  地形管理器: 可行走=%s, 在斜坡上=%s", tostring(walkable), tostring(onSlope)))
    end
    
    print(string.format("  帧率: %.1f FPS", self.averageFPS))
    print("----------------------------------------")
end

-- 新增：获取位置历史
function MovementSystem:getPositionHistory(entityId)
    local entity = self.entities[entityId]
    if not entity then return {} end
    
    return entity._positionHistory
end

-- 新增：获取最近的移动轨迹
function MovementSystem:getRecentMovement(entityId, seconds)
    local entity = self.entities[entityId]
    if not entity then return {} end
    
    local recentPositions = {}
    local cutoffTime = self.currentTime - seconds
    
    for i = #entity._positionHistory, 1, -1 do
        local pos = entity._positionHistory[i]
        if pos.time >= cutoffTime then
            table.insert(recentPositions, 1, pos)
        else
            break
        end
    end
    
    return recentPositions
end

-- 重置运动系统
function MovementSystem:reset()
    self.entities = {}
    
    self.isSprinting = false
    self.sprintDirection = 0
    self.lastKeyPressTime = {A = 0, D = 0}
    self.lastAPressed = false
    self.lastDPressed = false
    self.rollTimer = 0
    self.rollDirection = 0
    self.lastShiftPressed = false
    self.currentTime = 0
    self.frameCount = 0
    self.currentTimestep = self.baseTimestep
    self.frameTimes = {}
    self.averageFPS = 60
    self.cachedProperties = nil
    self.lastPropertyUpdate = 0
    self._transitionInProgress = false
    self.currentSceneTransitionTime = 0
    self._lastAdaptationTime = 0
    self._adaptationCount = 0
    self._levelManager = nil
    self._terrainManager = nil
    self._isFirstUpdate = true
    
    -- 重置Boss触发器状态
    self._bossTriggerDetected = false
    self._bossTriggerData = nil
    
    -- 保留地面平台，不清除它们
    -- self.groundPlatforms = {}  -- 不清除，由关卡管理器管理
    
    print("自适应帧率运动系统已重置")
end

-- 获取地面平台数量
function MovementSystem:getGroundPlatformCount()
    return #self.groundPlatforms
end

-- 获取调试信息
function MovementSystem:getDebugInfo()
    local entityPositions = {}
    
    for id, entity in pairs(self.entities) do
        entityPositions[id] = {
            x = entity.position.x,
            y = entity.position.y,
            isGrounded = entity.isGrounded,
            onSlope = entity.currentSlope ~= nil,
            historySize = #entity._positionHistory
        }
    end
    
    return {
        entityCount = tableCount(self.entities),
        groundPlatformCount = #self.groundPlatforms,
        averageFPS = self.averageFPS,
        currentTimestep = self.currentTimestep,
        isSprinting = self.isSprinting,
        bounds = self.bounds,
        frameCount = self.frameCount,
        currentTime = self.currentTime,
        adaptationCount = self._adaptationCount,
        entityPositions = entityPositions,
        positionTracking = self._positionTracking,
        hasTerrainManager = self._terrainManager ~= nil,
        bossTriggerDetected = self._bossTriggerDetected
    }
end

-- 数学符号函数
function math.sign(x)
    if x > 0 then return 1
    elseif x < 0 then return -1
    else return 0 end
end

-- 辅助函数：计算表中元素数量
local function tableCount(tbl)
    local count = 0
    for _ in pairs(tbl) do
        count = count + 1
    end
    return count
end

return MovementSystem